﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Reflection;

namespace VeryCodes.Common
{
    /// <summary>
    /// 给类用于枚举类型[Enum]的处理
    /// </summary>

    public class EnumHelper
    {
        /// <summary>
        /// 无参s构造函数
        /// </summary>
        public EnumHelper()
        {

        }

        /// <summary>
        /// 获得某个Enum类型的绑定列表
        /// </summary>
        /// <param name="enumType">枚举的类型，例如：typeof(Sex)</param>
        /// <returns>
        /// 返回一个DataTable
        /// DataTable 有两列：    "Text"    : System.String;
        ///                       "Value"    : System.Char
        /// </returns>
        public static DataTable GetEnumList(Type enumType)
        {
            if (enumType.IsEnum != true)
            {    //不是枚举的要报错
                throw new InvalidOperationException();
            }

            //建立DataTable的列信息
            DataTable dt = new DataTable();
            dt.Columns.Add("Text", typeof(System.String));
            dt.Columns.Add("Value", typeof(System.String));

            //获得特性Description的类型信息
            Type typeDescription = typeof(DescriptionAttribute);

            //获得枚举的字段信息（因为枚举的值实际上是一个static的字段的值）
            System.Reflection.FieldInfo[] fields = enumType.GetFields();

            //检索所有字段
            try
            {
                foreach (FieldInfo field in fields)
                {

                    //过滤掉一个不是枚举值的，记录的是枚举的源类型
                    if (field.FieldType.IsEnum == true)
                    {
                        DataRow dr = dt.NewRow();

                        // 通过字段的名字得到枚举的值
                        // 枚举的值如果是long的话，ToChar会有问题，但这个不在本文的讨论范围之内
                        dr["Value"] = Convert.ToString((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null));

                        //获得这个字段的所有自定义特性，这里只查找Description特性
                        object[] arr = field.GetCustomAttributes(typeDescription, true);
                        if (arr.Length > 0)
                        {
                            //因为Description这个自定义特性是不允许重复的，所以我们只取第一个就可以了！
                            DescriptionAttribute aa = (DescriptionAttribute)arr[0];
                            //获得特性的描述值，也就是‘男’‘女’等中文描述
                            dr["Text"] = aa.Description;
                        }
                        else
                        {
                            //如果没有特性描述（-_-!忘记写了吧~）那么就显示英文的字段名
                            dr["Text"] = field.Name;
                        }
                        dt.Rows.Add(dr);
                    }


                }
            }
            catch
            {
            }

            return dt;
        }

        /// <summary>
        /// 获取枚举值的详细文本
        /// </summary>
        /// <param name="e">object</param>
        /// <param name="enumType">枚举类型</param>
        /// <returns></returns>
        public static string GetEnumDescription(object e, Type enumType)
        {
            //获取字段信息
            System.Reflection.FieldInfo[] ms = enumType.GetFields();
            int value;
            Type t = enumType;
            foreach (System.Reflection.FieldInfo f in ms)
            {
                //判断名称是否相等

                try
                {
                    value = (int)enumType.InvokeMember(f.Name, BindingFlags.GetField, null, null, null);
                    if (value != (int)e)
                        continue;
                }
                catch
                {
                    continue;
                }


                //反射出自定义属性

                foreach (Attribute attr in f.GetCustomAttributes(true))
                {
                    //类型转换找到一个Description，用Description作为成员名称
                    System.ComponentModel.DescriptionAttribute dscript = attr as System.ComponentModel.DescriptionAttribute;
                    if (dscript != null)
                        return dscript.Description;
                }
            }

            //如果没有检测到合适的注释，则用默认名称
            return e.ToString();

            //string s = Enum.GetName(typeof(EnumApplyStatus),EnumApplyStatus.Approving);
        }

        /// <summary>
        /// 获取枚举值的详细文本
        /// </summary>
        /// <param name="e">object</param>
        /// <returns>枚举值的文本</returns>
        public static string GetEnumDescription(object e)
        {
            //获取字段信息
            System.Reflection.FieldInfo[] ms = e.GetType().GetFields();

            Type t = e.GetType();
            foreach (System.Reflection.FieldInfo f in ms)
            {
                //判断名称是否相等
                if (f.Name != e.ToString()) continue;

                //反射出自定义属性
                foreach (Attribute attr in f.GetCustomAttributes(true))
                {
                    //类型转换找到一个Description，用Description作为成员名称
                    System.ComponentModel.DescriptionAttribute dscript = attr as System.ComponentModel.DescriptionAttribute;
                    if (dscript != null)
                        return dscript.Description;
                }

            }

            //如果没有检测到合适的注释，则用默认名称
            return e.ToString();
        }
    }
}
